package com.bookrecomm.dao;

import com.bookrecomm.entity.Book;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
 * 图书数据访问接口
 * 提供图书相关的数据库操作方法
 */
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {

    /**
     * 根据ISBN查找图书
     * @param isbn ISBN编号
     * @return 图书对象（可能为空）
     */
    Optional<Book> findByIsbn(String isbn);

    /**
     * 根据标题模糊查询图书
     * @param title 标题关键词
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    Page<Book> findByTitleContaining(String title, Pageable pageable);

    /**
     * 根据作者模糊查询图书
     * @param author 作者关键词
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    Page<Book> findByAuthorContaining(String author, Pageable pageable);

    /**
     * 根据出版社模糊查询图书
     * @param publisher 出版社关键词
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    Page<Book> findByPublisherContaining(String publisher, Pageable pageable);

    /**
     * 查询热门图书（根据销量）
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    @Query("SELECT b FROM Book b WHERE b.status = 1 ORDER BY b.sales DESC")
    Page<Book> findHotBooks(Pageable pageable);

    /**
     * 查询新书上架（根据出版日期）
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    @Query("SELECT b FROM Book b WHERE b.status = 1 ORDER BY b.publishDate DESC")
    Page<Book> findNewBooks(Pageable pageable);

    /**
     * 查询高评分图书
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    @Query("SELECT b FROM Book b WHERE b.status = 1 AND b.ratingCount > 10 ORDER BY b.rating DESC")
    Page<Book> findHighRatedBooks(Pageable pageable);

    /**
     * 根据分类ID查询图书
     * @param categoryId 分类ID
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    @Query("SELECT b FROM Book b JOIN b.categories c WHERE c.id = :categoryId AND b.status = 1")
    Page<Book> findByCategoryId(@Param("categoryId") Long categoryId, Pageable pageable);

    /**
     * 根据标签ID查询图书
     * @param tagId 标签ID
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    @Query("SELECT b FROM Book b JOIN b.tags t WHERE t.id = :tagId AND b.status = 1")
    Page<Book> findByTagId(@Param("tagId") Long tagId, Pageable pageable);

    /**
     * 综合搜索图书（标题、作者、出版社、描述）
     * @param keyword 搜索关键词
     * @param pageable 分页参数
     * @return 图书分页列表
     */
    @Query("SELECT b FROM Book b WHERE b.status = 1 AND (b.title LIKE %:keyword% OR b.author LIKE %:keyword% OR b.publisher LIKE %:keyword% OR b.description LIKE %:keyword%)")
    Page<Book> searchBooks(@Param("keyword") String keyword, Pageable pageable);

    /**
     * 根据多个ID查询图书列表
     * @param ids ID列表
     * @return 图书列表
     */
    @Query("SELECT b FROM Book b WHERE b.id IN :ids AND b.status = 1")
    List<Book> findByIds(@Param("ids") List<Long> ids);

    /**
     * 查询相似图书（同分类、同作者）
     * @param bookId 图书ID
     * @param limit 限制数量
     * @return 图书列表
     */
    @Query(value = "SELECT b.* FROM books b " +
            "JOIN book_categories bc1 ON b.id = bc1.book_id " +
            "JOIN book_categories bc2 ON bc1.category_id = bc2.category_id " +
            "WHERE bc2.book_id = :bookId AND b.id != :bookId AND b.status = 1 " +
            "GROUP BY b.id ORDER BY COUNT(*) DESC, b.rating DESC LIMIT :limit", nativeQuery = true)
    List<Book> findSimilarBooks(@Param("bookId") Long bookId, @Param("limit") int limit);

    /**
     * 统计各分类图书数量
     * @return 分类ID和对应的图书数量
     */
    @Query("SELECT c.id, COUNT(b) FROM Book b JOIN b.categories c WHERE b.status = 1 GROUP BY c.id")
    List<Object[]> countBooksByCategory();

    /**
     * 统计各标签图书数量
     * @return 标签ID和对应的图书数量
     */
    @Query("SELECT t.id, COUNT(b) FROM Book b JOIN b.tags t WHERE b.status = 1 GROUP BY t.id")
    List<Object[]> countBooksByTag();

    /**
     * 根据用户的分类和标签偏好推荐图书
     * @param categoryIds 分类ID列表
     * @param tagIds 标签ID列表
     * @param limit 限制数量
     * @return 推荐图书列表
     */
    @Query(value = "SELECT DISTINCT b.* FROM books b "
            + "LEFT JOIN book_categories bc ON b.id = bc.book_id "
            + "LEFT JOIN book_tags bt ON b.id = bt.book_id "
            + "WHERE (bc.category_id IN (:categoryIds) OR bt.tag_id IN (:tagIds)) "
            + "AND b.status = 1 ORDER BY b.rating DESC LIMIT :limit", nativeQuery = true)
    List<Book> findRecommendedBooks(@Param("categoryIds") List<Long> categoryIds, @Param("tagIds") List<Long> tagIds, @Param("limit") int limit);
    
    /**
     * 查询销量最高的前10本图书
     * @return 图书列表
     */
    List<Book> findTop10ByOrderBySalesDesc();
    
    /**
     * 查询最新添加的前10本图书（根据创建时间）
     * @return 图书列表
     */
    List<Book> findTop10ByOrderByCreatedAtDesc();
}
